#pragma once

#include <vector>
#include <utility>

namespace sorting
{
    template <typename T>
    void DirectInsertionSort(std::vector<T> &vec);

    template <typename T>
    void BinaryInsertionSort(std::vector<T> &vec);

    template <typename T>
    void ShellSort_Exp2(std::vector<T> &vec);

    template <typename T>
    void ShellSort_Knuth(std::vector<T> &vec);

    template <typename T>
    void ShellSort_Sedgewick(std::vector<T> &vec);

    template <typename T>
    void DirectSelectionSort(std::vector<T> &vec);

    template <typename T>
    void BubbleSort(std::vector<T> &vec);

    template <typename T>
    void CocktailSort(std::vector<T> &vec);

    template <typename T>
    void QuickSort(std::vector<T> &vec, std::size_t left, std::size_t right);

    template <typename T>
    void QuickSort(std::vector<T> &vec);

    template <typename T>
    void MergeSort(std::vector<T> &vec, std::size_t left, std::size_t right);

    template <typename T>
    void MergeSort(std::vector<T> &vec);

    template <typename T>
    void HeapSort(std::vector<T> &vec);

    template <typename T>
    typename std::enable_if<std::is_integral<T>::value>::type
    RadixSort(std::vector<T> &vec);
} // namespace sorting

#include "sorting/direct_insertion_sort.hpp"
#include "sorting/binary_insertion_sort.hpp"
#include "sorting/shell_sort.hpp"
#include "sorting/direct_selection_sort.hpp"
#include "sorting/bubble_sort.hpp"
#include "sorting/quick_sort.hpp"
#include "sorting/merge_sort.hpp"
#include "sorting/heap_sort.hpp"
#include "sorting/radix_sort.hpp"